/* jshint esversion: 8 */

/**
 * ImportStepTwo
 */
layui.define(['jquery', 'yunj', "ImportStep", "form", "table", "validate"], function (exports) {

    let win = window;
    let doc = document;
    let $ = layui.jquery;
    let ImportStep = layui.ImportStep;
    let form = layui.form;
    let table = layui.table;
    let validate = layui.validate;

    class ImportStepTwo extends ImportStep {

        constructor(importObj) {
            super(importObj, "two", "第二步：勾选数据");
            this.uploadFileData = {};                   // 上传文件数据，有sheet则为{sheet=>[item1,..],...}，反之为[item1,..]
            this.dataId = 1;                            // 上传文件数据id
            this.dataTotalCount = 0;                    // 上传文件数据总量
            this.dataCheckCount = 0;                    // 上传文件选中数据总量
            this.sheetTableBoxEl = null;                // 工作表表格父级元素
            this.dataTotalCountEl = null;               // 上传文件数据总量元素
            this.dataCheckCountEl = null;               // 上传文件选中数据总量元素
            this.colsValidateAttr = {};                  // 表头验证器参数，有sheet：{sheet1:{rule:{...},dataTitle:{...}},...}，无sheet：{rule:{...},dataTitle:{...}}
        }

        async render(refresh = false) {
            let that = this;
            let uploadFile = that.getCurrUploadFile();
            if (!uploadFile) throw new Error("请选择上传文件");
            if (!refresh) return;
            that._setContentBoxHtml();
            await that._setUploadFileData(uploadFile);
            that._renderSheetTable();
        }

        // 设置内容区域html
        _setContentBoxHtml() {
            let that = this;
            if (that.contentBoxEl.html().length <= 0) {
                that.contentBoxEl.html(`<div class="yunj-import-step-content-row action-box">
                                            <div class="tips">注意！！！请勾选要上传的数据行</div>
                                            <div class="action">
                                                <div class="tips">共<em class="total-count">${that._getDataTotalCount()}</em>条，选中<em class="check-count">${that._getDataCheckCount()}</em>条</div>
                                                <form class="layui-form layui-form-pane" lay-filter="${that._getActionFormId()}">
                                                    <div class="layui-form-item" style="margin: 0">
                                                        <input type="checkbox" title="全选" lay-filter="check-all">
                                                    </div>
                                                </form>
                                            </div>
                                        </div>
                                        <div class="layui-tab yunj-import-step-content-row sheet-table"></div>`);
                that.sheetTableBoxEl = that.contentBoxEl.find(".sheet-table");
                that.dataTotalCountEl = that.contentBoxEl.find(".total-count");
                that.dataCheckCountEl = that.contentBoxEl.find(".check-count");
            }
            // 初始化操作表单
            $("input[type=checkbox][lay-filter='check-all']").attr("checked", false);
            form.render('checkbox', that._getActionFormId());
            // 初始化sheet表格html空
            that.sheetTableBoxEl.html("");
        }

        // 操作表单id
        _getActionFormId() {
            return `yunj_import_${this.importId}_step_two_form_action`;
        }

        // 获取上传数据总量
        _getDataTotalCount() {
            return this.dataTotalCount;
        }

        // 设置上传数据总量
        _setDataTotalCount(count) {
            this.dataTotalCount = count;
            this.dataTotalCountEl.html(count);
        }

        // 获取上传数据选中量
        _getDataCheckCount() {
            return this.dataCheckCount;
        }

        // 设置上传数据选中量
        _setDataCheckCount(count = null) {
            let that = this;
            if (count === null) {
                count = 0;
                // 获取所有表格选中数据
                if (that.isSetSheet()) {
                    that.importObj.rawArgs.sheet.forEach(sheet => {
                        count += table.checkStatus(that._getSheetTableSingleId(sheet)).data.length;
                    });
                } else {
                    count += table.checkStatus(that._getSheetTableSingleId()).data.length;
                }
            }
            that.dataCheckCount = count;
            that.dataCheckCountEl.html(count);
        }

        /**
         * 根据工作表原始数据获取表头对应数据
         * @private
         * @param {array} rows  原始数据，多行数据
         * @param {object} cols  表头配置
         * @return {array}string}   返回数据|错误信息
         */
        _getItemsByRows(rows, cols) {
            let that = this;
            let items = [];
            for (let i = 0, l = rows.length; i < l; i++) {
                let row = rows[i];  // 单行数据
                let item = {_id: that.dataId++, _rawData: row};
                for (let k in cols) {
                    if (!cols.hasOwnProperty(k)) continue;
                    let title = cols[k].title;
                    if (!row.hasOwnProperty(title)) return '上传文件数据格式错误，详见示例模板';
                    item[k] = row[title];
                }
                items.push(item);
            }
            return items;
        }

        // 设置上传文件数据
        _setUploadFileData(uploadFile) {
            let that = this;
            return new Promise(resolve => {
                let reader = new FileReader();
                reader.onload = function (e) {
                    let data = e.target.result;
                    let workbook = XLSX.read(data, {type: 'binary'});
                    that.dataId = 1;  // 自定义数据id
                    let dataTotalCount = 0; // 数据总量

                    if (that.isSetSheet()) {
                        that.uploadFileData = {};
                        workbook.SheetNames.forEach(sheet => {
                            // 导入数据描述的工作表排除
                            if (sheet === that.importObj.stepMap.one.templetDescSheetName) return;
                            let rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
                            let cols = that.getCols(sheet);
                            let items = that._getItemsByRows(rows, cols);
                            if (yunj.isString(items)) {
                                yunj.msg(items);
                                throw new Error(items);
                            }
                            that.uploadFileData[sheet] = items;
                            dataTotalCount += items.length;
                        });
                    } else {
                        that.uploadFileData = [];
                        let rows = XLSX.utils.sheet_to_json(workbook.Sheets[that.importObj.defaultSheetName]);
                        let cols = that.getCols();
                        let items = that._getItemsByRows(rows, cols);
                        if (yunj.isString(items)) {
                            yunj.msg(items);
                            throw new Error(items);
                        }
                        that.uploadFileData = items;
                        dataTotalCount += items.length;
                    }
                    that._setDataTotalCount(dataTotalCount);
                    that._setDataCheckCount(0);
                    resolve();
                };
                reader.readAsBinaryString(uploadFile);
            });
        }

        // 获取单一的sheet表格结构
        _getSheetTableSingleLayout(isShow = false, sheet = "") {
            let id = this._getSheetTableSingleId(sheet);
            return `<div class="layui-tab-item${isShow ? ' layui-show' : ''}">
                        <table class="layui-table" id="${id}" lay-filter="${id}"></table>
                    </div>`;
        }

        // 获取单一的sheet表格id
        _getSheetTableSingleId(sheet = "") {
            return `yunj_import_${this.importId}_step_two_table${sheet ? `_${sheet}` : ""}`;
        }

        // 渲染工作表lay表格
        _renderSheetLayTable(cols, items, sheet = "") {
            let that = this;

            let layTableCols = [{field: 'id', type: 'checkbox'}];
            for (let field in cols) {
                if (!cols.hasOwnProperty(field)) continue;
                layTableCols.push({field: field, type: 'normal', title: cols[field].title});
            }
            let args = {
                elem: `#${that._getSheetTableSingleId(sheet)}`,
                url: '/admin/empty',
                method: 'post',
                contentType: 'application/json',
                parseData: function (res) {
                    return {
                        "code": 0,
                        "msg": 'success',
                        "count": 0,
                        "data": items
                    };
                },
                page: false,
                loading: true,
                text: {none: '暂无相关数据'},
                cols: [layTableCols],
                done: function (res) {
                    table.resize(this.id);
                    table.on(`checkbox(${this.id})`, function (obj) {
                        that._setDataCheckCount();
                    });
                }
            };
            table.render(args);
        }

        // 渲染工作表表格
        _renderSheetTable() {
            let that = this;
            let titleHtml = `<ul class="layui-tab-title"></ul>`;
            let contentHtml = `<div class="layui-tab-content"></div>`;
            if (that.isSetSheet()) {
                that.sheetTableBoxEl.html(titleHtml + contentHtml);
                let titleBoxEl = that.sheetTableBoxEl.find(".layui-tab-title");
                let contentBoxEl = that.sheetTableBoxEl.find(".layui-tab-content");
                let i = 0;
                for (let sheet in that.uploadFileData) {
                    if (!that.uploadFileData.hasOwnProperty(sheet)) continue;
                    titleBoxEl.append(`<li class="${i === 0 ? 'layui-this' : ''}">${sheet}</li>`);
                    contentBoxEl.append(that._getSheetTableSingleLayout(i === 0, sheet));
                    let cols = that.getCols(sheet);
                    let items = that.uploadFileData[sheet];
                    that._renderSheetLayTable(cols, items, sheet);
                    i++;
                }
            } else {
                that.sheetTableBoxEl.html(contentHtml);
                let contentBoxEl = that.sheetTableBoxEl.find(".layui-tab-content");
                contentBoxEl.append(that._getSheetTableSingleLayout(true));
                let cols = that.getCols();
                let items = that.uploadFileData;
                that._renderSheetLayTable(cols, items);
            }
        }

        /**
         * 获取选中数据，并校验
         * @returns {*}
         */
        getCheckData() {
            let that = this;
            let data = {
                importItems: [],    // 选中数据，没有做sheet区分放在一起的，用于上传
                sheetItems: {},     // 选中数据
                totalCount: 0,      // 选中总量
                errorCount: 0,      // 错误量
            };
            if (that.isSetSheet()) {
                data.sheetItems = {};
                for (let sheet in that.uploadFileData) {
                    if (!that.uploadFileData.hasOwnProperty(sheet)) continue;
                    that._setCheckData(data, sheet);
                }
            } else {
                data.sheetItems = [];
                that._setCheckData(data);
            }
            return data;
        }

        _setCheckData(data, sheet = false) {
            let that = this;
            let checkedData = table.checkStatus(that._getSheetTableSingleId(sheet));
            let dataCount = checkedData.data.length;
            if (dataCount <= 0) return;
            data.totalCount += dataCount;
            let rows = checkedData.data;
            rows.forEach(v => {
                let validateAttr = that._getColsValidateAttr(sheet);
                validate.create({
                    rule: validateAttr.rule
                });
                v._state = JSON.parse(JSON.stringify(that.importObj.DataStateEnum.WAIT));
                let res = validate.check(v, validateAttr.dataTitle);
                if (!res) {
                    v._state.code = that.importObj.DataStateEnum.ERROR.code;
                    v._state.tips = that.importObj.DataStateEnum.ERROR.tips+":"+validate.getError();
                    data.errorCount++;
                }
                let {LAY_TABLE_INDEX, _id, _rawData, _state, ...row} = v;
                let item = {id: _id,state: _state, row: row};
                if(sheet!==false) item.sheet = sheet;
                data.importItems.push(item);
            });
            if (sheet) {
                data.sheetItems[sheet] = rows;
            } else {
                data.sheetItems = rows;
            }
        }

        // 获取表头校验属性，rule和dataTitle
        _getColsValidateAttr(sheet = false) {
            let that = this;
            let colsValidateAttr = that.colsValidateAttr;
            if (!yunj.isEmptyObj(colsValidateAttr)) {
                if (sheet === false) {
                    return colsValidateAttr;
                } else {
                    if (colsValidateAttr.hasOwnProperty(sheet)) return colsValidateAttr[sheet];
                }
            }
            let _attr = {rule: {}, dataTitle: {}};
            let cols = that.getCols(sheet);
            for (let k in cols) {
                if (!cols.hasOwnProperty(k)) continue;
                let col = cols[k];
                if (col.verify.length <= 0) continue;
                _attr.rule[k] = col.verify;
                _attr.dataTitle[k] = col.title;
            }
            sheet === false ? (colsValidateAttr = _attr):(colsValidateAttr[sheet] = _attr);
            that.colsValidateAttr = colsValidateAttr;
            return _attr;
        }

        setEventBind() {
            let that = this;

            form.on("checkbox(check-all)", function (data) {
                let all = data.elem.checked;
                that.sheetTableBoxEl.find(".layui-tab-content .layui-tab-item").each(function (e) {
                    let checkAllEl = $(this).find(".layui-table-header thead:first tr:first th:first .layui-form-checkbox");
                    let isChecked = checkAllEl.hasClass("layui-form-checked");
                    if (all) {
                        if (isChecked) return true;
                    } else {
                        if (!isChecked) return true;
                    }
                    checkAllEl.click();
                });
            });

        }

    }

    exports('ImportStepTwo', ImportStepTwo);
});